package me.hl.reflect;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;

/**
 * Created by Planck on 2016/2/18.
 */
public class ReflectDemo {

    private static Logger logger = LoggerFactory.getLogger(ReflectDemo.class);

    public Class getclass() {
        //三种获得class的方法
        Class class1;
        Class class2;
        Class class3;

        try {
            class1 = Class.forName("me.hl.reflect.Person");
            class2 = new Person().getClass();
            class3 = Person.class;
            System.out.println(class1.getName());
            System.out.println(class2.getName());
            System.out.println(class3.getName());
            return class1;
        } catch (Exception e) {

        }
        return null;
    }

    @Test
    public void invoke() throws Exception {
        Class personClass = getclass();
        Method[] methods = personClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            if (method.getName().equals("speak")) {
                method.invoke(personClass.newInstance());
            }
        }

    }

    @Test
    public void getName() {
        Field[] fields = Person.class.getDeclaredFields();
        Lists.newArrayList(fields).forEach((a) -> {
            logger.info("field = {} type = {}", a.getName(), a.getType());
        });
    }


    @Test
    public void ObjectToMap() {
        Person person = new Person("1", "2", "3");
        Class cls = person.getClass();
        Field[] fields = cls.getDeclaredFields();
        Object value;
        Map<String, Object> map = Maps.newHashMap();
        //TODO 还有boolean的is开头的。后面在写吧。毕竟只是demo
        for (Field field : fields) {
            String methodName = "get" + Optional.ofNullable(field.getName()).map((x) -> x.substring(0, 1).toUpperCase() + x.substring(1)).get();
            Method method = null;
            try {
                method = cls.getMethod(methodName, new Class[0]);
                value = method.invoke(person, new Object[]{});
                map.put(methodName, value);
            } catch (Exception e) {
                logger.error("", e);
            }
        }

        logger.info("map={}", JSON.toJSONString(map));

    }


    /**
     * 测试强制赋值filed属性
     *
     * @throws Exception
     */
    @Test
    public void testModifyPrivateFiled() throws Exception {
        Class cls = Person.class;
        Field field = cls.getDeclaredField("name");
        field.setAccessible(true);
        Person person = (Person) cls.newInstance();
        field.set(person, "name");
        logger.info("person = {}", JSON.toJSONString(person));
    }

}
